package com.example.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.blog.dao.mapper.ArticleMapper;
import com.example.blog.dao.mapper.CollectionMapper;
import com.example.blog.dao.mapper.LikeMapper;
import com.example.blog.dao.mapper.UserMapper;
import com.example.blog.dao.pojo.Article;
import com.example.blog.dao.pojo.Collection;
import com.example.blog.dao.pojo.Like;
import com.example.blog.dao.pojo.User;
import com.example.blog.service.ArticleService;
import com.example.blog.service.LoginService;
import com.example.blog.service.UserService;
import com.example.blog.vo.ArticleVo;
import com.example.blog.vo.LoginUserVo;
import com.example.blog.vo.Result;
import com.example.blog.vo.UserVo;
import com.example.blog.vo.params.PageParams;
import com.mysql.cj.log.Log;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    @Lazy
    private LoginService loginService;
    @Autowired
    @Lazy
    private ArticleService articleService;
    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private LikeMapper likeMapper;
    @Autowired
    private CollectionMapper collectionMapper;

    @Override
    public User findUserInfoByToken(String token) {
        if (StringUtils.isBlank(token)) {
            return null;
        }
        return userMapper.selectById(loginService.checkToken(token).getId());
    }

    @Override
    public Result findUserLikes(String token) {
        if (StringUtils.isBlank(token)) {
            return null;
        }
        Long userId = loginService.checkToken(token).getId();
        LambdaQueryWrapper<Like> likeLQM = new LambdaQueryWrapper<>();
        likeLQM.eq(Like::getUserId,userId);
        likeLQM.orderByDesc(Like::getCreateTime);
        List<Like> likes = likeMapper.selectList(likeLQM);
        List<Long> likeArticleIds = new ArrayList<>();
        if (likes.size() > 0){
            for (Like like : likes) {
                likeArticleIds.add(like.getArticleId());
            }
        }
        PageParams pageParams = new PageParams();
        Page<Article> page = new Page<Article>(pageParams.getPage(),pageParams.getPageSize());
        LambdaQueryWrapper<Article> articleLambdaQueryWrapper = new LambdaQueryWrapper<>();
        articleLambdaQueryWrapper.in(Article::getAid,likeArticleIds);

        Page<Article> articlePage = articleMapper.selectPage(page, articleLambdaQueryWrapper);
        List<Article> records = articlePage.getRecords();
        List<ArticleVo> articleVoList = articleService.copyList(records);
        for (ArticleVo articleVo : articleVoList) {
            if (likeArticleIds.contains(articleVo.getId())){
                articleVo.setIsLike(true);
            }
        }


        LambdaQueryWrapper<Collection> collectionLQM = new LambdaQueryWrapper<>();
        collectionLQM.eq(Collection::getUserId,userId);
        List<Collection> collections = collectionMapper.selectList(collectionLQM);
        List<Long> collectionArticleIds = new ArrayList<>();
        if (collections.size() > 0){
            for (Collection collection : collections) {
                collectionArticleIds.add(collection.getArticleId());
            }
            for (ArticleVo articleVo : articleVoList) {
                if (collectionArticleIds.contains(articleVo.getId())){
                    articleVo.setIsCollection(true);
                }
            }
        }


        return Result.success(articleVoList);
    }

    @Override
    public Result findUserCollection(String token) {
        if (StringUtils.isBlank(token)) {
            return null;
        }
        Long userId = loginService.checkToken(token).getId();
        LambdaQueryWrapper<Collection> collectionLQM = new LambdaQueryWrapper<>();
        collectionLQM.eq(Collection::getUserId,userId);
        collectionLQM.orderByDesc(Collection::getCreateTime);
        List<Collection> collections = collectionMapper.selectList(collectionLQM);
        List<Long> collectionArticleIds = new ArrayList<>();
        if (collections.size() > 0){
            for (Collection collection : collections) {
                collectionArticleIds.add(collection.getArticleId());
            }
        }
        PageParams pageParams = new PageParams();
        Page<Article> page = new Page<Article>(pageParams.getPage(),pageParams.getPageSize());
        LambdaQueryWrapper<Article> articleLambdaQueryWrapper = new LambdaQueryWrapper<>();
        articleLambdaQueryWrapper.in(Article::getAid,collectionArticleIds);

        Page<Article> articlePage = articleMapper.selectPage(page, articleLambdaQueryWrapper);
        List<Article> records = articlePage.getRecords();
        List<ArticleVo> articleVoList = articleService.copyList(records);
        for (ArticleVo articleVo : articleVoList) {
            if (collectionArticleIds.contains(articleVo.getId())){
                articleVo.setIsLike(true);
            }
        }


        LambdaQueryWrapper<Like> likeLQM = new LambdaQueryWrapper<>();
        likeLQM.eq(Like::getUserId,userId);
        List<Like> likes = likeMapper.selectList(likeLQM);
        List<Long> likeArticleIds = new ArrayList<>();
        if (likes.size() > 0){
            for (Like like : likes) {
                likeArticleIds.add(like.getArticleId());
            }
        }

        for (ArticleVo articleVo : articleVoList) {
            if (likeArticleIds.contains(articleVo.getId())){
                articleVo.setIsLike(true);
            }
        }



        return Result.success(articleVoList);
    }

    @Override
    public UserVo findUserVoById(Long id) {
        User user = userMapper.selectById(id);
        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(user,userVo);
        return userVo;
    }

    @Override
    public User findUser(String account, String password) {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getAccount,account);
        lambdaQueryWrapper.eq(User::getPassword,password);
        lambdaQueryWrapper.select(User::getAccount,User::getId,User::getAvatar,User::getNickname);
        lambdaQueryWrapper.last("limit 1");
        return userMapper.selectOne(lambdaQueryWrapper);
    }

    @Override
    public Result findUserByToken(String token) {
        /**
         * 1、合法性校验
         * 2、解析是否成功
         * 3、redis是否存在
         */
        if (StringUtils.isBlank(token)){
            return Result.fail(-1000,"授权过期");
        }
        User user = loginService.checkToken(token);
        if (user == null){
            return Result.fail(-1000,"密码错误");
        }
        LoginUserVo loginUserVo = new LoginUserVo();
        loginUserVo.setId(user.getId());
        loginUserVo.setNickname(user.getNickname());
        loginUserVo.setAccount(user.getAccount());
        loginUserVo.setAvatar(user.getAvatar());
        return Result.success(loginUserVo);
    }

    @Override
    public User findUserByAccount(String account) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getAccount,account);
        queryWrapper.last("limit 1");
        return userMapper.selectOne(queryWrapper);
    }

    @Override
    public void save(User user) {
        userMapper.insert(user);
    }

    @Override
    public Result findUserPublish(String token) {
        PageParams pageParams = new PageParams();
        pageParams.setStatus("new");
        pageParams.setAuthorId(loginService.checkToken(token).getId());
        return articleService.listArticle(token, pageParams);
    }
    @Override
    public Result updateUserInfo(User user) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getId, user.getId());
        return Result.success(this.userMapper.update(user, queryWrapper));
    }
}
